package com.hoopchina.util;

import java.io.InputStream;
import java.net.URLEncoder;

import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

import com.hoopchina.service.Networking;

import android.location.Location;

/**
 * Geography utility provided by online google geocoding apis
 * @author Si Wei
 *
 */
public class GeoUtils {
	private static String          mCityName;
	private static double          mLatitude;
	private static double          mLongitude;
	private static final String    mGeocodingUrl = 
		"http://maps.google.com/maps/api/geocode/xml?latlng=%d,%d&language=zh&sensor=false&oe=utf8";
	private static final String    mDeGeocodingUrl = 
		"http://maps.google.com/maps/api/geocode/xml?address=%s&language=zh&sensor=false&oe=utf8";
		
	
	/**
	 * Solve location to city name
	 * @param aLatitude
	 * @param aLongitude
	 * @return
	 */
	public static String getCityNameFromLocation( double aLatitude, double aLongitude ) {
		mCityName = "";
        try {
//        		new URL("http://maps.google.com/maps/api/geocode/xml?latlng=" 
//        				+ Double.toString( aLatitude ) 
//        				+ "," 
//        				+ Double.toString( aLongitude )
//        				+ "&language=zh&sensor=false&oe=utf8");
            // using SAX parse this small xml file
            SAXParserFactory saxFactory=SAXParserFactory.newInstance();  
            saxFactory.setNamespaceAware( true );  
            saxFactory.setValidating( false );  
            SAXParser parser = saxFactory.newSAXParser();  
            
            InputStream inputStream = Networking.getStreamFromUrl( 
            		String.format( mGeocodingUrl, aLatitude, aLongitude ) );
            parser.parse( inputStream, new DefaultHandler() {
                private String currentTag = "";
                private boolean done = false;
                @Override  
                
                public void startElement(String uri, String localName,  
                        String qName, org.xml.sax.Attributes attributes)  
                        throws SAXException {
                	if ( !done ) {
                		currentTag = localName;
                	}
                }
                
                @Override  
                public void characters(char[] ch, int start, int length)
                        throws SAXException {
                	if ( !done ) {
	                    String value = new String( ch, start, length ).trim();
	                    if ( value == null || value.equals( "" ) )
	                        return;
	                    if ( currentTag.equals( "long_name" ) ) {  
	                        mCityName = value;  
	                    }
                	}
                }
                
                @Override
                public void endElement(String uri, String localName,
                        String qName) throws SAXException {
                	if ( currentTag.equals( "long_name" ) && !done ) {
                		done = true;
                	}
                    super.endElement( uri, localName, qName );
                }
            } );
        }
        catch ( Exception ex ) {
            ex.printStackTrace();
        }
		return mCityName;
	}
	
	/**
	 * Solve city back to location, could return null
	 * @param aCityName
	 * @return
	 */
	public static Location getLocationFromCityName( String aCityName ) {
		mLatitude = 0;
		mLongitude = 0;
		
        try {
//        		new URL("http://maps.google.com/maps/api/geocode/xml?address=" 
//        				+ 
//        				+ "&language=zh&sensor=false&oe=utf8");
            // using SAX parse this small xml file
            SAXParserFactory saxFactory=SAXParserFactory.newInstance();
            saxFactory.setNamespaceAware( true );
            saxFactory.setValidating( false );
            SAXParser parser = saxFactory.newSAXParser();
            
            InputStream inputStream = Networking.getStreamFromUrl( 
            		String.format( mDeGeocodingUrl, URLEncoder.encode( aCityName, "UTF-8" ) ) );
            parser.parse( inputStream, new DefaultHandler() {
                private String currentTag = "";
                private boolean done = false;
                @Override  
                
                public void startElement(String uri, String localName,
                        String qName, org.xml.sax.Attributes attributes)
                        throws SAXException {
                	if ( !done ) {
                		currentTag = localName;
                	}
                }
                
                @Override  
                public void characters(char[] ch, int start, int length)
                        throws SAXException {
                	if ( !done ) {
	                    String value = new String( ch, start, length ).trim();
	                    if ( value == null || value.equals( "" ) )
	                        return;
	                    
	                    if ( currentTag.equals( "lat" ) ) {  
	                        mLatitude = Double.valueOf( value );  
	                    }
	                    if ( currentTag.equals( "lng" ) ) {
	                    	mLongitude = Double.valueOf( value );
	                    }
	                    
	                    if ( !done && mLatitude != 0 && mLongitude != 0 ) {
	                    	done = true;
	                    }
                	}
                }
            } );
        }
        catch ( Exception ex ) {
            ex.printStackTrace();
        }
		
		if ( mLatitude != 0 && mLongitude != 0 ) {
			Location location = new Location( "" );
			location.setLatitude( mLatitude );
			location.setLongitude( mLongitude );
			return location;
		}
		else {
			return null;
		}
	}
}
